package xyz.scootaloo.kami.cloud.lang

import io.vertx.core.Future
import io.vertx.core.Promise
import io.vertx.core.json.JsonObject
import io.vertx.kotlin.coroutines.await
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.sql.Timestamp
import java.util.StringJoiner

/**
 * @author flutterdash@qq.com
 * @since 2022/4/10 16:47
 */

typealias CodeBlock<T> = () -> T
typealias CommandBlock = () -> Unit
typealias PromiseBlock<T> = (Promise<T>) -> Unit

fun getLogger(name: String): Logger = LoggerFactory.getLogger(name)

fun currentTimeMillis(): Long = System.currentTimeMillis()

fun timestamp(time: Long = currentTimeMillis()): String {
    return Timestamp(time).toString()
}

inline fun <T> T?.ifNotNull(handle: (T) -> Unit) {
    if (this != null)
        handle(this)
}

fun Iterable<String>.filterNotBlank(): List<String> {
    return filter { it.isBlank() }
}

operator fun JsonObject.set(key: String, value: Any) {
    put(key, value)
}

fun <T> blocking(block: PromiseBlock<T>): Worker<T> = Worker(false, block)

fun blocking(block: CommandBlock): Worker<Unit> = Worker(false) { promise ->
    try {
        block()
        promise.complete()
    } catch (err: Throwable) {
        promise.fail(err)
    }
}

class Worker<T>(
    private val sync: Boolean = false,
    private val block: PromiseBlock<T>
) {
    suspend fun await(): T {
        return submit().await()
    }

    fun submit(): Future<T> {
        return Global.VERTX_REF.executeBlocking(block, sync)
    }
}